/*
 *  Copyright 2004 Blandware (http://www.blandware.com)
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.blandware.atleap.webapp.taglib.core.grid;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import java.io.IOException;

/**
 * <p>Tag that renders to pager. If there are no pages to show or only one page
 * exists, body of this tag will not be rendered. The main function of this tag
 * is exactly to determine whether we need to render some controls (links) that
 * are called pager because they help navigate through data pages.
 * <br />
 * This tag is only valid when nested within <em>grid</em> tag.
 * </p>
 * <p>
 * Allowed attributes are:
 * <ul>
 * <li>
 * <b>pageCount</b> - number of links to pages to display. Default is 10.
 * </li>
 * </ul>
 * </p>
 * <p>
 * Here's an example:
 * <pre>
 * &lt;atleap:pager pageCount=&quot;10&quot;&gt;
 *     &lt;td colspan=&quot;${3 + additionalCells}&quot; align=&quot;center&quot;&gt;
 *         &lt;atleap:message key=&quot;core.grid.pager.title&quot; /&gt;&amp;nbsp;
 *         &lt;atleap:firstPage&gt;&lt;img src=&quot;&lt;atleap:rewriteUrl href=&quot;/images/theme/atleap_admin/first.gif&quot; /&gt;&quot; border=&quot;0&quot; alt=&quot;&lt;atleap:message key=&quot;core.grid.pager.first&quot;/&gt;&quot; title=&quot;&lt;atleap:message key=&quot;core.grid.pager.first&quot;/&gt;&quot; /&gt;&lt;/atleap:firstPage&gt;
 *         &lt;atleap:prevPage&gt;&lt;img src=&quot;&lt;atleap:rewriteUrl href=&quot;/images/theme/atleap_admin/prev.gif&quot; /&gt;&quot; border=&quot;0&quot; alt=&quot;&lt;atleap:message key=&quot;core.grid.pager.prev&quot;/&gt;&quot; title=&quot;&lt;atleap:message key=&quot;core.grid.pager.prev&quot;/&gt;&quot; /&gt;&lt;/atleap:prevPage&gt;
 *         &lt;atleap:pagesIterator&gt;
 *             &lt;atleap:page&gt;${pageNumber}&amp;nbsp;&lt;/atleap:page&gt;
 *             &lt;atleap:currentPage&gt;&lt;b&gt;${pageNumber}&lt;/b&gt;&amp;nbsp;&lt;/atleap:currentPage&gt;
 *         &lt;/atleap:pagesIterator&gt;
 *         &lt;atleap:nextPage&gt;&lt;img src=&quot;&lt;atleap:rewriteUrl href=&quot;/images/theme/atleap_admin/next.gif&quot; /&gt;&quot; border=&quot;0&quot; alt=&quot;&lt;atleap:message key=&quot;core.grid.pager.next&quot;/&gt;&quot; title=&quot;&lt;atleap:message key=&quot;core.grid.pager.next&quot;/&gt;&quot; /&gt;&lt;/atleap:nextPage&gt;
 *         &lt;atleap:lastPage&gt;&lt;img src=&quot;&lt;atleap:rewriteUrl href=&quot;/images/theme/atleap_admin/last.gif&quot; /&gt;&quot; border=&quot;0&quot; alt=&quot;&lt;atleap:message key=&quot;core.grid.pager.last&quot;/&gt;&quot; title=&quot;&lt;atleap:message key=&quot;core.grid.pager.last&quot;/&gt;&quot; /&gt;&lt;/atleap:lastPage&gt;
 *     &lt;/td&gt;
 * &lt;/atleap:pager&gt;
 * </pre>
 * </p>
 * <p><a href="PagerTag.java.html"><i>View Source</i></a></p>
 *
 * @author Sergey Zubtsovskiy <a href="mailto:sergey.zubtsovskiy@blandware.com">&lt;sergey.zubtsovskiy@blandware.com&gt;</a>
 * @version $Revision: 1.11 $ $Date: 2008/03/19 18:07:10 $
 * @see PagesIteratorTag
 * @see PageTag
 * @see CurrentPageTag
 * @jsp.tag name="pager"
 * body-content="scriptless"
 * @see com.blandware.atleap.webapp.taglib.core.grid.GridTag
 */
public class PagerTag extends SimpleTagSupport {

	protected transient final Log log = LogFactory.getLog(PagerTag.class);

	/**
	 * Number of page links to display
	 */
	protected Integer pageCount = null;

	/**
	 * Number of last page
	 */
	protected Integer lastPageNumber = null;

	/**
     * Returns number of page links to display
     *
	 * @return number of page links to display
	 * @jsp.attribute required="false"
	 * rtexprvalue="true"
	 * type="java.lang.Integer"
	 * description="Number of page links to display"
	 */
	public Integer getPageCount() {
		return pageCount;
	}

    /**
     * Sets number of page links to display
     *
     * @param pageCount number of page links to display to set
     */
	public void setPageCount(Integer pageCount) {
		this.pageCount = pageCount;
	}

    /**
     * Returns number of last page
     *
     * @return number of last page
     */
	protected Integer getLastPageNumber() {
		return this.lastPageNumber;
	}

    /**
     * Processes the tag
     *
     * @throws JspException
     * @throws IOException
     */
	public void doTag() throws JspException, IOException {

		PageContext pageContext = (PageContext) getJspContext();

		// This tag is only valid when nested within 'grid' tag, so check this
		GridTag parentGridTag = (GridTag) findAncestorWithClass(this, GridTag.class);

		if ( parentGridTag == null ) {
			JspTagException e = new JspTagException("Parent tag is invalid! This tag is only valid when nested within 'grid' tag");
			throw e;
		}

		// Set page count (number of links to pages to show) and calculate number of last page

		if ( pageCount == null ) {
			pageCount = new Integer(10);
		}

		int total = parentGridTag.getGrid().getTotal().intValue();
		int pageSize = parentGridTag.getPageSize().intValue();
        if (pageSize <= 0) {
            throw new IllegalArgumentException("Page size must be positive");
        }

		if ( total > pageSize ) {

			int last = total / pageSize;
			if ( total % pageSize > 0 ) {
				last += 1;
			}

			if ( last <= 1 ) {
				last = 1;
			}

			lastPageNumber = new Integer(last);

			JspFragment body = getJspBody();
			if ( body != null ) {
				body.invoke(null);
			}
		}
	}

}
